#ifndef __UITREEVIEW_H__
#define __UITREEVIEW_H__

#pragma once

#include <set>
#include <list>

namespace DuiLib
{
    class CTreeViewUI;
    class CCheckBoxUI;
    class CLabelUI;
    class COptionUI;

    class DUILIB_API CTreeNodeUI : public CListContainerElementUI
    {
    public:
        CTreeNodeUI(CTreeNodeUI* _ParentNode = NULL);
        ~CTreeNodeUI(void);

    public:
        LPCTSTR GetClass() const;
        LPVOID  GetInterface(LPCTSTR pstrName);
        void    DoEvent(TEventUI& event);
        void    Invalidate();
        bool    Select(bool bSelect = true, bool bTriggerEvent = true);

        bool    Add(CControlUI* _pTreeNodeUI);
        bool    AddAt(CControlUI* pControl, int iIndex);

        void    SetVisibleTag(bool _IsVisible);
        bool    GetVisibleTag();
        void    SetItemText(LPCTSTR pstrValue);
        CDuiString    GetItemText();
        void    CheckBoxSelected(bool _Selected);
        bool    IsCheckBoxSelected() const;
        bool    IsHasChild() const;
        long    GetTreeViewLevel() const;
        long    GetNodeLevel() const;
    private:
        long    SetNodeLevel();
    public:
        bool    AddChildNode(CTreeNodeUI* _pTreeNodeUI,
                             bool child_node_is_first_child = false);
        bool    RemoveAt(CTreeNodeUI* _pTreeNodeUI);
        void    SetParentNode(CTreeNodeUI* _pParentTreeNode);
        CTreeNodeUI* GetParentNode();
        long    GetCountChild();
        void    SetTreeView(CTreeViewUI* _CTreeViewUI);
        CTreeViewUI* GetTreeView();
        CTreeNodeUI* GetChildNode(int _nIndex);
        void    SetVisibleFolderBtn(bool _IsVisibled);
        bool    GetVisibleFolderBtn();
        void    SetVisibleCheckBtn(bool _IsVisibled);
        bool    GetVisibleCheckBtn();
        void    SetItemTextColor(DWORD _dwItemTextColor);
        DWORD    GetItemTextColor() const;
        void    SetItemHotTextColor(DWORD _dwItemHotTextColor);
        DWORD    GetItemHotTextColor() const;
        void    SetSelItemTextColor(DWORD _dwSelItemTextColor);
        DWORD    GetSelItemTextColor() const;
        void    SetSelItemHotTextColor(DWORD _dwSelHotItemTextColor);
        DWORD    GetSelItemHotTextColor() const;

        void    SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

        CDuiPtrArray GetTreeNodes();

        int GetTreeIndex();
        int GetNodeIndex();

        size_t GetPickOrder()const;
        void SetPickOrder(size_t new_order);

        void AddSelectedChild(CTreeNodeUI* pChild);
        void RemoveSelectedChild(CTreeNodeUI* pChild);

        size_t GetSelectedChildCount()const;

        void SetChildSelect(bool is_select, bool notify = false);

        void SetSelectedChildState(bool new_state, bool notify = false);
        bool IsAncestor(CTreeNodeUI* pDescendant) const;

        void SetEnabled(bool bEnable)override;
    private:
        CTreeNodeUI* GetLastNode();
        CTreeNodeUI* CalLocation(CTreeNodeUI* _pTreeNodeUI);
    public:
        CHorizontalLayoutUI* GetTreeNodeHoriznotal() const
        {
            return pHoriz;
        };
        CCheckBoxUI* GetFolderButton() const
        {
            return pFolderButton;
        };
        CLabelUI* GetDottedLine() const
        {
            return pDottedLine;
        };
        CCheckBoxUI* GetCheckBox() const
        {
            return pCheckBox;
        };
        COptionUI* GetItemButton() const
        {
            return pItemButton;
        };
        size_t m_PickOrder;
    protected:
        long    m_iTreeLavel;
        bool    m_bIsVisable;
        bool    m_bIsCheckBox;
        DWORD    m_dwItemTextColor;
        DWORD    m_dwItemHotTextColor;
        DWORD    m_dwSelItemTextColor;
        DWORD    m_dwSelItemHotTextColor;

        CTreeViewUI* m_pOnwerTreeView;
        CHorizontalLayoutUI* pHoriz;
        CCheckBoxUI* pFolderButton;
        CLabelUI* pDottedLine;
        CCheckBoxUI* pCheckBox;
        COptionUI* pItemButton;

        CTreeNodeUI* pParentTreeNode;
        std::set<DuiLib::CTreeNodeUI*> m_AllSelectedChild;
        CDuiPtrArray mTreeNodes;
    };

    struct SetCmp
    {
        bool operator()(const DuiLib::CTreeNodeUI* _Left,
                        const DuiLib::CTreeNodeUI* _Right) const
        {
            return _Left->GetPickOrder() < _Right->GetPickOrder();
        }
    };


    class DUILIB_API CTreeViewUI : public CListUI, public INotifyUI
    {
    public:
        CTreeViewUI(void);
        ~CTreeViewUI(void);

    public:
        virtual LPCTSTR GetClass() const;
        virtual LPVOID    GetInterface(LPCTSTR pstrName);
        virtual bool Add(CControlUI* pControl);
        virtual bool AddAt(CControlUI* pControl, int iIndex);
        virtual bool Remove(CControlUI* pControl, bool bDoNotDestroy = false);
        virtual bool RemoveAt(int iIndex, bool bDoNotDestroy = false);
        virtual void RemoveAll();

        long AddAt(CTreeNodeUI* pControl, int iIndex);
        bool AddAt(CTreeNodeUI* pControl, CTreeNodeUI* _IndexNode);

        virtual bool OnCheckBoxChanged(void* param);
        virtual bool OnFolderChanged(void* param);
        virtual bool OnDBClickItem(void* param);
        virtual bool SetItemCheckBox(bool _Selected, CTreeNodeUI* _TreeNode = NULL);
        virtual void SetItemExpand(bool _Expanded, CTreeNodeUI* _TreeNode = NULL);
        virtual void Notify(TNotifyUI& msg);

        virtual void SetVisibleFolderBtn(bool _IsVisibled);
        virtual bool GetVisibleFolderBtn();
        virtual void SetVisibleCheckBtn(bool _IsVisibled);
        virtual bool GetVisibleCheckBtn();
        virtual void SetItemMinWidth(UINT _ItemMinWidth);
        virtual UINT GetItemMinWidth();
        virtual void SetItemTextColor(DWORD _dwItemTextColor);
        virtual void SetItemHotTextColor(DWORD _dwItemHotTextColor);
        virtual void SetSelItemTextColor(DWORD _dwSelItemTextColor);
        virtual void SetSelItemHotTextColor(DWORD _dwSelHotItemTextColor);

        virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

        size_t GetSelectedNodeCount(int ignore_node_level = -1);
        size_t GetSelectedNodeCount2()const;
        DuiLib::CTreeNodeUI* GetSelectedTreeNode()const;
        void CheckSelected(CTreeNodeUI* pItem, bool _select);
        void GetSelectChildNode(CTreeNodeUI* pItem, std::list<DuiLib::CTreeNodeUI*>& out_list, bool get_all = false);
        const std::set<DuiLib::CTreeNodeUI*, SetCmp>& GetSelectNode()const;
        DuiLib::CTreeNodeUI* FindTreeNodeByItemText(LPCTSTR pNodeItemText);
        DuiLib::CTreeNodeUI* FindTreeNodeByUserData(LPCTSTR pUserData);
        long GetLevel()const;

        void SetEnabled(bool new_status);
    protected:
        long m_Level;
        UINT m_uItemMinWidth;
        bool m_bVisibleFolderBtn;
        bool m_bVisibleCheckBtn;
        bool m_SelecteMultiple = true;
        bool m_SelecteBranch = true;
        size_t m_SelectedCount = 0;
        std::set<DuiLib::CTreeNodeUI*, SetCmp> m_Selected;
        DuiLib::CTreeNodeUI* m_OldSelected = nullptr;
        DuiLib::CTreeNodeUI* m_NewSelected = nullptr;
    };


}


#endif // __UITREEVIEW_H__
